﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace PacManLib
{
    /// <summary>
    /// Holds information about the Pac-Man board or screen, inlcuding the
    /// positions of the pellets and players.
    /// </summary>
    public class Board
    {
        #region Public types

        /// <summary>
        /// The various types of item that make up the Pac-Man board.
        /// </summary>
        public enum Item
        {
            Wall,
            Pellet,
            PowerPellet,
            Empty
        }

        #endregion

        #region Public methods and properties

        /// <summary>
        /// Constructor.
        /// </summary>
        public Board()
        {
            // We create the player info for the ghosts...
            for(int i=0; i<NUM_GHOSTS; ++i)
            {
                m_ghostInfos[i] = new PlayerInfo();
                m_ghostInfos[i].CanTurnAround = false;
                m_ghostInfos[i].GhostID = i;
            }

            // Pac-Man is allowed to turn around...
            m_pacManInfo.CanTurnAround = true;

            resetBoard();
        }

        /// <summary>
        /// Gets the number of ghosts in the game.
        /// </summary>
        public static int NumberOfGhosts
        {
            get { return NUM_GHOSTS; }
        }

        /// <summary>
        /// The position returned to a ghost if it cannot see Pac-Man.
        /// </summary>
        public static Point UnknownPacmanPosition
        {
            get { return m_unknownPacManPosition; }
        }

        /// <summary>
        /// Gets the two-dimensional array of items that make
        /// up the board.
        /// </summary>
        public Item[,] Items
        {
            get { return m_board; }
        }

        /// <summary>
        /// Gets the position and direction of the Pac-Man.
        /// </summary>
        public PlayerInfo PacMan
        {
            get { return m_pacManInfo; }
        }

        /// <summary>
        /// Gets the positions and directions of the ghosts.
        /// </summary>
        public PlayerInfo[] Ghosts
        {
            get { return m_ghostInfos; }
        }

        /// <summary>
        /// Gets the board width;
        /// </summary>
        public int Width
        {
            get { return BOARD_WIDTH; }
        }

        /// <summary>
        /// Gets the board height.
        /// </summary>
        public int Height
        {
            get { return BOARD_HEIGHT; }
        }
        
        /// <summary>
        /// Gets the number of turns remaining if Pac-Man is in a 
        /// powered-up state. Zero if he is not powered up.
        /// </summary>
        public int PowerUpTurnsRemaining
        {
            get { return m_powerUpTurnsRemaining; }
            set { m_powerUpTurnsRemaining = value; }
        }

        /// <summary>
        /// Returns true if the position passed in is the 
        /// position of the Pac-Man.
        /// </summary>
        public bool isPacManPosition(int x, int y)
        {
            return new Point(x, y) == m_pacManInfo.Position;
        }

        /// <summary>
        /// Returns true if the position passed in is the 
        /// position of a ghost.
        /// </summary>
        public bool isGhostPosition(int x, int y)
        {
            return m_ghostInfos.Any(g => g.Position == new Point(x, y));
        }

        /// <summary>
        /// Resets the board back to its initial state. This includes the
        /// walls and the pellets, but not the players.
        /// </summary>
        public void resetBoard()
        {
            resetPacManPosition();
            resetGhostPositions();
            resetBoardItems();
        }

        /// <summary>
        /// Sets the Pac-Man to his starting position.
        /// </summary>
        public void resetPacManPosition()
        {
            // We set the starting position of the Pac-Man...
            m_pacManInfo.Position = new Point(13, 23);
            m_pacManInfo.DesiredDirection = PlayerInfo.Direction.Left;
        }

        /// <summary>
        /// Sets the ghosts to their starting positions.
        /// </summary>
        public void resetGhostPositions()
        {
            // We set the starting positions of the ghosts...
            for (int i = 0; i < NUM_GHOSTS; ++i)
            {
                resetGhostPosition(i);
            }
        }

        /// <summary>
        /// Resets the position of one ghost.
        /// </summary>
        public void resetGhostPosition(int ghostIndex)
        {
            m_ghostInfos[ghostIndex].Position = new Point(14, 11);
        }

        /// <summary>
        /// Returns a copy of the board.
        /// </summary>
        public Board createCopy()
        {
            Board copy = new Board();
            copy.m_board = (Item[,])m_board.Clone();
            copy.m_pacManInfo = m_pacManInfo.createCopy();
            for (int i = 0; i < NUM_GHOSTS; ++i)
            {
                copy.m_ghostInfos[i] = m_ghostInfos[i].createCopy();
            }
            copy.m_powerUpTurnsRemaining = m_powerUpTurnsRemaining;
            return copy;
        }

        #endregion

        #region Private functions

        /// <summary>
        /// Sets up the board items (pellets and so on) to their
        /// original positions.
        /// </summary>
        private void resetBoardItems()
        {
            // We set up the board...
            m_board[0, 0] = Item.Wall;
            m_board[0, 1] = Item.Wall;
            m_board[0, 2] = Item.Wall;
            m_board[0, 3] = Item.Wall;
            m_board[0, 4] = Item.Wall;
            m_board[0, 5] = Item.Wall;
            m_board[0, 6] = Item.Wall;
            m_board[0, 7] = Item.Wall;
            m_board[0, 8] = Item.Wall;
            m_board[0, 9] = Item.Wall;
            m_board[0, 10] = Item.Empty;
            m_board[0, 11] = Item.Empty;
            m_board[0, 12] = Item.Empty;
            m_board[0, 13] = Item.Wall;
            m_board[0, 14] = Item.Empty;
            m_board[0, 15] = Item.Wall;
            m_board[0, 16] = Item.Empty;
            m_board[0, 17] = Item.Empty;
            m_board[0, 18] = Item.Empty;
            m_board[0, 19] = Item.Wall;
            m_board[0, 20] = Item.Wall;
            m_board[0, 21] = Item.Wall;
            m_board[0, 22] = Item.Wall;
            m_board[0, 23] = Item.Wall;
            m_board[0, 24] = Item.Wall;
            m_board[0, 25] = Item.Wall;
            m_board[0, 26] = Item.Wall;
            m_board[0, 27] = Item.Wall;
            m_board[0, 28] = Item.Wall;
            m_board[0, 29] = Item.Wall;
            m_board[0, 30] = Item.Wall;

            m_board[1, 0] = Item.Wall;
            m_board[1, 1] = Item.Pellet;
            m_board[1, 2] = Item.Pellet;
            m_board[1, 3] = Item.PowerPellet;
            m_board[1, 4] = Item.Pellet;
            m_board[1, 5] = Item.Pellet;
            m_board[1, 6] = Item.Pellet;
            m_board[1, 7] = Item.Pellet;
            m_board[1, 8] = Item.Pellet;
            m_board[1, 9] = Item.Wall;
            m_board[1, 10] = Item.Empty;
            m_board[1, 11] = Item.Empty;
            m_board[1, 12] = Item.Empty;
            m_board[1, 13] = Item.Wall;
            m_board[1, 14] = Item.Empty;
            m_board[1, 15] = Item.Wall;
            m_board[1, 16] = Item.Empty;
            m_board[1, 17] = Item.Empty;
            m_board[1, 18] = Item.Empty;
            m_board[1, 19] = Item.Wall;
            m_board[1, 20] = Item.Pellet;
            m_board[1, 21] = Item.Pellet;
            m_board[1, 22] = Item.Pellet;
            m_board[1, 23] = Item.PowerPellet;
            m_board[1, 24] = Item.Wall;
            m_board[1, 25] = Item.Wall;
            m_board[1, 26] = Item.Pellet;
            m_board[1, 27] = Item.Pellet;
            m_board[1, 28] = Item.Pellet;
            m_board[1, 29] = Item.Pellet;
            m_board[1, 30] = Item.Wall;

            m_board[2, 0] = Item.Wall;
            m_board[2, 1] = Item.Pellet;
            m_board[2, 2] = Item.Wall;
            m_board[2, 3] = Item.Wall;
            m_board[2, 4] = Item.Wall;
            m_board[2, 5] = Item.Pellet;
            m_board[2, 6] = Item.Wall;
            m_board[2, 7] = Item.Wall;
            m_board[2, 8] = Item.Pellet;
            m_board[2, 9] = Item.Wall;
            m_board[2, 10] = Item.Empty;
            m_board[2, 11] = Item.Empty;
            m_board[2, 12] = Item.Empty;
            m_board[2, 13] = Item.Wall;
            m_board[2, 14] = Item.Empty;
            m_board[2, 15] = Item.Wall;
            m_board[2, 16] = Item.Empty;
            m_board[2, 17] = Item.Empty;
            m_board[2, 18] = Item.Empty;
            m_board[2, 19] = Item.Wall;
            m_board[2, 20] = Item.Pellet;
            m_board[2, 21] = Item.Wall;
            m_board[2, 22] = Item.Wall;
            m_board[2, 23] = Item.Pellet;
            m_board[2, 24] = Item.Wall;
            m_board[2, 25] = Item.Wall;
            m_board[2, 26] = Item.Pellet;
            m_board[2, 27] = Item.Wall;
            m_board[2, 28] = Item.Wall;
            m_board[2, 29] = Item.Pellet;
            m_board[2, 30] = Item.Wall;

            m_board[3, 0] = Item.Wall;
            m_board[3, 1] = Item.Pellet;
            m_board[3, 2] = Item.Wall;
            m_board[3, 3] = Item.Empty;
            m_board[3, 4] = Item.Wall;
            m_board[3, 5] = Item.Pellet;
            m_board[3, 6] = Item.Wall;
            m_board[3, 7] = Item.Wall;
            m_board[3, 8] = Item.Pellet;
            m_board[3, 9] = Item.Wall;
            m_board[3, 10] = Item.Empty;
            m_board[3, 11] = Item.Empty;
            m_board[3, 12] = Item.Empty;
            m_board[3, 13] = Item.Wall;
            m_board[3, 14] = Item.Empty;
            m_board[3, 15] = Item.Wall;
            m_board[3, 16] = Item.Empty;
            m_board[3, 17] = Item.Empty;
            m_board[3, 18] = Item.Empty;
            m_board[3, 19] = Item.Wall;
            m_board[3, 20] = Item.Pellet;
            m_board[3, 21] = Item.Wall;
            m_board[3, 22] = Item.Wall;
            m_board[3, 23] = Item.Pellet;
            m_board[3, 24] = Item.Pellet;
            m_board[3, 25] = Item.Pellet;
            m_board[3, 26] = Item.Pellet;
            m_board[3, 27] = Item.Wall;
            m_board[3, 28] = Item.Wall;
            m_board[3, 29] = Item.Pellet;
            m_board[3, 30] = Item.Wall;

            m_board[4, 0] = Item.Wall;
            m_board[4, 1] = Item.Pellet;
            m_board[4, 2] = Item.Wall;
            m_board[4, 3] = Item.Empty;
            m_board[4, 4] = Item.Wall;
            m_board[4, 5] = Item.Pellet;
            m_board[4, 6] = Item.Wall;
            m_board[4, 7] = Item.Wall;
            m_board[4, 8] = Item.Pellet;
            m_board[4, 9] = Item.Wall;
            m_board[4, 10] = Item.Empty;
            m_board[4, 11] = Item.Empty;
            m_board[4, 12] = Item.Empty;
            m_board[4, 13] = Item.Wall;
            m_board[4, 14] = Item.Empty;
            m_board[4, 15] = Item.Wall;
            m_board[4, 16] = Item.Empty;
            m_board[4, 17] = Item.Empty;
            m_board[4, 18] = Item.Empty;
            m_board[4, 19] = Item.Wall;
            m_board[4, 20] = Item.Pellet;
            m_board[4, 21] = Item.Wall;
            m_board[4, 22] = Item.Wall;
            m_board[4, 23] = Item.Wall;
            m_board[4, 24] = Item.Wall;
            m_board[4, 25] = Item.Wall;
            m_board[4, 26] = Item.Pellet;
            m_board[4, 27] = Item.Wall;
            m_board[4, 28] = Item.Wall;
            m_board[4, 29] = Item.Pellet;
            m_board[4, 30] = Item.Wall;

            m_board[5, 0] = Item.Wall;
            m_board[5, 1] = Item.Pellet;
            m_board[5, 2] = Item.Wall;
            m_board[5, 3] = Item.Wall;
            m_board[5, 4] = Item.Wall;
            m_board[5, 5] = Item.Pellet;
            m_board[5, 6] = Item.Wall;
            m_board[5, 7] = Item.Wall;
            m_board[5, 8] = Item.Pellet;
            m_board[5, 9] = Item.Wall;
            m_board[5, 10] = Item.Wall;
            m_board[5, 11] = Item.Wall;
            m_board[5, 12] = Item.Wall;
            m_board[5, 13] = Item.Wall;
            m_board[5, 14] = Item.Empty;
            m_board[5, 15] = Item.Wall;
            m_board[5, 16] = Item.Wall;
            m_board[5, 17] = Item.Wall;
            m_board[5, 18] = Item.Wall;
            m_board[5, 19] = Item.Wall;
            m_board[5, 20] = Item.Pellet;
            m_board[5, 21] = Item.Wall;
            m_board[5, 22] = Item.Wall;
            m_board[5, 23] = Item.Wall;
            m_board[5, 24] = Item.Wall;
            m_board[5, 25] = Item.Wall;
            m_board[5, 26] = Item.Pellet;
            m_board[5, 27] = Item.Wall;
            m_board[5, 28] = Item.Wall;
            m_board[5, 29] = Item.Pellet;
            m_board[5, 30] = Item.Wall;

            m_board[6, 0] = Item.Wall;
            m_board[6, 1] = Item.Pellet;
            m_board[6, 2] = Item.Pellet;
            m_board[6, 3] = Item.Pellet;
            m_board[6, 4] = Item.Pellet;
            m_board[6, 5] = Item.Pellet;
            m_board[6, 6] = Item.Pellet;
            m_board[6, 7] = Item.Pellet;
            m_board[6, 8] = Item.Pellet;
            m_board[6, 9] = Item.Pellet;
            m_board[6, 10] = Item.Pellet;
            m_board[6, 11] = Item.Pellet;
            m_board[6, 12] = Item.Pellet;
            m_board[6, 13] = Item.Pellet;
            m_board[6, 14] = Item.Pellet;
            m_board[6, 15] = Item.Pellet;
            m_board[6, 16] = Item.Pellet;
            m_board[6, 17] = Item.Pellet;
            m_board[6, 18] = Item.Pellet;
            m_board[6, 19] = Item.Pellet;
            m_board[6, 20] = Item.Pellet;
            m_board[6, 21] = Item.Pellet;
            m_board[6, 22] = Item.Pellet;
            m_board[6, 23] = Item.Pellet;
            m_board[6, 24] = Item.Pellet;
            m_board[6, 25] = Item.Pellet;
            m_board[6, 26] = Item.Pellet;
            m_board[6, 27] = Item.Wall;
            m_board[6, 28] = Item.Wall;
            m_board[6, 29] = Item.Pellet;
            m_board[6, 30] = Item.Wall;

            m_board[7, 0] = Item.Wall;
            m_board[7, 1] = Item.Pellet;
            m_board[7, 2] = Item.Wall;
            m_board[7, 3] = Item.Wall;
            m_board[7, 4] = Item.Wall;
            m_board[7, 5] = Item.Pellet;
            m_board[7, 6] = Item.Wall;
            m_board[7, 7] = Item.Wall;
            m_board[7, 8] = Item.Wall;
            m_board[7, 9] = Item.Wall;
            m_board[7, 10] = Item.Wall;
            m_board[7, 11] = Item.Wall;
            m_board[7, 12] = Item.Wall;
            m_board[7, 13] = Item.Wall;
            m_board[7, 14] = Item.Empty;
            m_board[7, 15] = Item.Wall;
            m_board[7, 16] = Item.Wall;
            m_board[7, 17] = Item.Wall;
            m_board[7, 18] = Item.Wall;
            m_board[7, 19] = Item.Wall;
            m_board[7, 20] = Item.Pellet;
            m_board[7, 21] = Item.Wall;
            m_board[7, 22] = Item.Wall;
            m_board[7, 23] = Item.Pellet;
            m_board[7, 24] = Item.Wall;
            m_board[7, 25] = Item.Wall;
            m_board[7, 26] = Item.Wall;
            m_board[7, 27] = Item.Wall;
            m_board[7, 28] = Item.Wall;
            m_board[7, 29] = Item.Pellet;
            m_board[7, 30] = Item.Wall;

            m_board[8, 0] = Item.Wall;
            m_board[8, 1] = Item.Pellet;
            m_board[8, 2] = Item.Wall;
            m_board[8, 3] = Item.Empty;
            m_board[8, 4] = Item.Wall;
            m_board[8, 5] = Item.Pellet;
            m_board[8, 6] = Item.Wall;
            m_board[8, 7] = Item.Wall;
            m_board[8, 8] = Item.Wall;
            m_board[8, 9] = Item.Wall;
            m_board[8, 10] = Item.Wall;
            m_board[8, 11] = Item.Wall;
            m_board[8, 12] = Item.Wall;
            m_board[8, 13] = Item.Wall;
            m_board[8, 14] = Item.Empty;
            m_board[8, 15] = Item.Wall;
            m_board[8, 16] = Item.Wall;
            m_board[8, 17] = Item.Wall;
            m_board[8, 18] = Item.Wall;
            m_board[8, 19] = Item.Wall;
            m_board[8, 20] = Item.Pellet;
            m_board[8, 21] = Item.Wall;
            m_board[8, 22] = Item.Wall;
            m_board[8, 23] = Item.Pellet;
            m_board[8, 24] = Item.Wall;
            m_board[8, 25] = Item.Wall;
            m_board[8, 26] = Item.Wall;
            m_board[8, 27] = Item.Wall;
            m_board[8, 28] = Item.Wall;
            m_board[8, 29] = Item.Pellet;
            m_board[8, 30] = Item.Wall;

            m_board[9, 0] = Item.Wall;
            m_board[9, 1] = Item.Pellet;
            m_board[9, 2] = Item.Wall;
            m_board[9, 3] = Item.Empty;
            m_board[9, 4] = Item.Wall;
            m_board[9, 5] = Item.Pellet;
            m_board[9, 6] = Item.Pellet;
            m_board[9, 7] = Item.Pellet;
            m_board[9, 8] = Item.Pellet;
            m_board[9, 9] = Item.Wall;
            m_board[9, 10] = Item.Wall;
            m_board[9, 11] = Item.Empty;
            m_board[9, 12] = Item.Empty;
            m_board[9, 13] = Item.Empty;
            m_board[9, 14] = Item.Empty;
            m_board[9, 15] = Item.Empty;
            m_board[9, 16] = Item.Empty;
            m_board[9, 17] = Item.Empty;
            m_board[9, 18] = Item.Empty;
            m_board[9, 19] = Item.Empty;
            m_board[9, 20] = Item.Pellet;
            m_board[9, 21] = Item.Wall;
            m_board[9, 22] = Item.Wall;
            m_board[9, 23] = Item.Pellet;
            m_board[9, 24] = Item.Pellet;
            m_board[9, 25] = Item.Pellet;
            m_board[9, 26] = Item.Pellet;
            m_board[9, 27] = Item.Wall;
            m_board[9, 28] = Item.Wall;
            m_board[9, 29] = Item.Pellet;
            m_board[9, 30] = Item.Wall;

            m_board[10, 0] = Item.Wall;
            m_board[10, 1] = Item.Pellet;
            m_board[10, 2] = Item.Wall;
            m_board[10, 3] = Item.Empty;
            m_board[10, 4] = Item.Wall;
            m_board[10, 5] = Item.Pellet;
            m_board[10, 6] = Item.Wall;
            m_board[10, 7] = Item.Wall;
            m_board[10, 8] = Item.Pellet;
            m_board[10, 9] = Item.Wall;
            m_board[10, 10] = Item.Wall;
            m_board[10, 11] = Item.Empty;
            m_board[10, 12] = Item.Wall;
            m_board[10, 13] = Item.Wall;
            m_board[10, 14] = Item.Wall;
            m_board[10, 15] = Item.Wall;
            m_board[10, 16] = Item.Wall;
            m_board[10, 17] = Item.Empty;
            m_board[10, 18] = Item.Wall;
            m_board[10, 19] = Item.Wall;
            m_board[10, 20] = Item.Pellet;
            m_board[10, 21] = Item.Wall;
            m_board[10, 22] = Item.Wall;
            m_board[10, 23] = Item.Pellet;
            m_board[10, 24] = Item.Wall;
            m_board[10, 25] = Item.Wall;
            m_board[10, 26] = Item.Pellet;
            m_board[10, 27] = Item.Wall;
            m_board[10, 28] = Item.Wall;
            m_board[10, 29] = Item.Pellet;
            m_board[10, 30] = Item.Wall;

            m_board[11, 0] = Item.Wall;
            m_board[11, 1] = Item.Pellet;
            m_board[11, 2] = Item.Wall;
            m_board[11, 3] = Item.Wall;
            m_board[11, 4] = Item.Wall;
            m_board[11, 5] = Item.Pellet;
            m_board[11, 6] = Item.Wall;
            m_board[11, 7] = Item.Wall;
            m_board[11, 8] = Item.Pellet;
            m_board[11, 9] = Item.Wall;
            m_board[11, 10] = Item.Wall;
            m_board[11, 11] = Item.Empty;
            m_board[11, 12] = Item.Wall;
            m_board[11, 13] = Item.Empty;
            m_board[11, 14] = Item.Empty;
            m_board[11, 15] = Item.Empty;
            m_board[11, 16] = Item.Wall;
            m_board[11, 17] = Item.Empty;
            m_board[11, 18] = Item.Wall;
            m_board[11, 19] = Item.Wall;
            m_board[11, 20] = Item.Pellet;
            m_board[11, 21] = Item.Wall;
            m_board[11, 22] = Item.Wall;
            m_board[11, 23] = Item.Pellet;
            m_board[11, 24] = Item.Wall;
            m_board[11, 25] = Item.Wall;
            m_board[11, 26] = Item.Pellet;
            m_board[11, 27] = Item.Wall;
            m_board[11, 28] = Item.Wall;
            m_board[11, 29] = Item.Pellet;
            m_board[11, 30] = Item.Wall;

            m_board[12, 0] = Item.Wall;
            m_board[12, 1] = Item.Pellet;
            m_board[12, 2] = Item.Pellet;
            m_board[12, 3] = Item.Pellet;
            m_board[12, 4] = Item.Pellet;
            m_board[12, 5] = Item.Pellet;
            m_board[12, 6] = Item.Wall;
            m_board[12, 7] = Item.Wall;
            m_board[12, 8] = Item.Pellet;
            m_board[12, 9] = Item.Empty;
            m_board[12, 10] = Item.Empty;
            m_board[12, 11] = Item.Empty;
            m_board[12, 12] = Item.Wall;
            m_board[12, 13] = Item.Empty;
            m_board[12, 14] = Item.Empty;
            m_board[12, 15] = Item.Empty;
            m_board[12, 16] = Item.Wall;
            m_board[12, 17] = Item.Empty;
            m_board[12, 18] = Item.Wall;
            m_board[12, 19] = Item.Wall;
            m_board[12, 20] = Item.Pellet;
            m_board[12, 21] = Item.Pellet;
            m_board[12, 22] = Item.Pellet;
            m_board[12, 23] = Item.Pellet;
            m_board[12, 24] = Item.Wall;
            m_board[12, 25] = Item.Wall;
            m_board[12, 26] = Item.Pellet;
            m_board[12, 27] = Item.Pellet;
            m_board[12, 28] = Item.Pellet;
            m_board[12, 29] = Item.Pellet;
            m_board[12, 30] = Item.Wall;

            m_board[13, 0] = Item.Wall;
            m_board[13, 1] = Item.Wall;
            m_board[13, 2] = Item.Wall;
            m_board[13, 3] = Item.Wall;
            m_board[13, 4] = Item.Wall;
            m_board[13, 5] = Item.Pellet;
            m_board[13, 6] = Item.Wall;
            m_board[13, 7] = Item.Wall;
            m_board[13, 8] = Item.Wall;
            m_board[13, 9] = Item.Wall;
            m_board[13, 10] = Item.Wall;
            m_board[13, 11] = Item.Empty;
            m_board[13, 12] = Item.Wall;
            m_board[13, 13] = Item.Empty;
            m_board[13, 14] = Item.Empty;
            m_board[13, 15] = Item.Empty;
            m_board[13, 16] = Item.Wall;
            m_board[13, 17] = Item.Empty;
            m_board[13, 18] = Item.Wall;
            m_board[13, 19] = Item.Wall;
            m_board[13, 20] = Item.Wall;
            m_board[13, 21] = Item.Wall;
            m_board[13, 22] = Item.Wall;
            m_board[13, 23] = Item.Pellet;
            m_board[13, 24] = Item.Wall;
            m_board[13, 25] = Item.Wall;
            m_board[13, 26] = Item.Wall;
            m_board[13, 27] = Item.Wall;
            m_board[13, 28] = Item.Wall;
            m_board[13, 29] = Item.Pellet;
            m_board[13, 30] = Item.Wall;

            m_board[14, 0] = Item.Wall;
            m_board[14, 1] = Item.Wall;
            m_board[14, 2] = Item.Wall;
            m_board[14, 3] = Item.Wall;
            m_board[14, 4] = Item.Wall;
            m_board[14, 5] = Item.Pellet;
            m_board[14, 6] = Item.Wall;
            m_board[14, 7] = Item.Wall;
            m_board[14, 8] = Item.Wall;
            m_board[14, 9] = Item.Wall;
            m_board[14, 10] = Item.Wall;
            m_board[14, 11] = Item.Empty;
            m_board[14, 12] = Item.Wall;
            m_board[14, 13] = Item.Empty;
            m_board[14, 14] = Item.Empty;
            m_board[14, 15] = Item.Empty;
            m_board[14, 16] = Item.Wall;
            m_board[14, 17] = Item.Empty;
            m_board[14, 18] = Item.Wall;
            m_board[14, 19] = Item.Wall;
            m_board[14, 20] = Item.Wall;
            m_board[14, 21] = Item.Wall;
            m_board[14, 22] = Item.Wall;
            m_board[14, 23] = Item.Pellet;
            m_board[14, 24] = Item.Wall;
            m_board[14, 25] = Item.Wall;
            m_board[14, 26] = Item.Wall;
            m_board[14, 27] = Item.Wall;
            m_board[14, 28] = Item.Wall;
            m_board[14, 29] = Item.Pellet;
            m_board[14, 30] = Item.Wall;

            m_board[15, 0] = Item.Wall;
            m_board[15, 1] = Item.Pellet;
            m_board[15, 2] = Item.Pellet;
            m_board[15, 3] = Item.Pellet;
            m_board[15, 4] = Item.Pellet;
            m_board[15, 5] = Item.Pellet;
            m_board[15, 6] = Item.Wall;
            m_board[15, 7] = Item.Wall;
            m_board[15, 8] = Item.Pellet;
            m_board[15, 9] = Item.Empty;
            m_board[15, 10] = Item.Empty;
            m_board[15, 11] = Item.Empty;
            m_board[15, 12] = Item.Wall;
            m_board[15, 13] = Item.Empty;
            m_board[15, 14] = Item.Empty;
            m_board[15, 15] = Item.Empty;
            m_board[15, 16] = Item.Wall;
            m_board[15, 17] = Item.Empty;
            m_board[15, 18] = Item.Wall;
            m_board[15, 19] = Item.Wall;
            m_board[15, 20] = Item.Pellet;
            m_board[15, 21] = Item.Pellet;
            m_board[15, 22] = Item.Pellet;
            m_board[15, 23] = Item.Pellet;
            m_board[15, 24] = Item.Wall;
            m_board[15, 25] = Item.Wall;
            m_board[15, 26] = Item.Pellet;
            m_board[15, 27] = Item.Pellet;
            m_board[15, 28] = Item.Pellet;
            m_board[15, 29] = Item.Pellet;
            m_board[15, 30] = Item.Wall;

            m_board[16, 0] = Item.Wall;
            m_board[16, 1] = Item.Pellet;
            m_board[16, 2] = Item.Wall;
            m_board[16, 3] = Item.Wall;
            m_board[16, 4] = Item.Wall;
            m_board[16, 5] = Item.Pellet;
            m_board[16, 6] = Item.Wall;
            m_board[16, 7] = Item.Wall;
            m_board[16, 8] = Item.Pellet;
            m_board[16, 9] = Item.Wall;
            m_board[16, 10] = Item.Wall;
            m_board[16, 11] = Item.Empty;
            m_board[16, 12] = Item.Wall;
            m_board[16, 13] = Item.Empty;
            m_board[16, 14] = Item.Empty;
            m_board[16, 15] = Item.Empty;
            m_board[16, 16] = Item.Wall;
            m_board[16, 17] = Item.Empty;
            m_board[16, 18] = Item.Wall;
            m_board[16, 19] = Item.Wall;
            m_board[16, 20] = Item.Pellet;
            m_board[16, 21] = Item.Wall;
            m_board[16, 22] = Item.Wall;
            m_board[16, 23] = Item.Pellet;
            m_board[16, 24] = Item.Wall;
            m_board[16, 25] = Item.Wall;
            m_board[16, 26] = Item.Pellet;
            m_board[16, 27] = Item.Wall;
            m_board[16, 28] = Item.Wall;
            m_board[16, 29] = Item.Pellet;
            m_board[16, 30] = Item.Wall;

            m_board[17, 0] = Item.Wall;
            m_board[17, 1] = Item.Pellet;
            m_board[17, 2] = Item.Wall;
            m_board[17, 3] = Item.Empty;
            m_board[17, 4] = Item.Wall;
            m_board[17, 5] = Item.Pellet;
            m_board[17, 6] = Item.Wall;
            m_board[17, 7] = Item.Wall;
            m_board[17, 8] = Item.Pellet;
            m_board[17, 9] = Item.Wall;
            m_board[17, 10] = Item.Wall;
            m_board[17, 11] = Item.Empty;
            m_board[17, 12] = Item.Wall;
            m_board[17, 13] = Item.Wall;
            m_board[17, 14] = Item.Wall;
            m_board[17, 15] = Item.Wall;
            m_board[17, 16] = Item.Wall;
            m_board[17, 17] = Item.Empty;
            m_board[17, 18] = Item.Wall;
            m_board[17, 19] = Item.Wall;
            m_board[17, 20] = Item.Pellet;
            m_board[17, 21] = Item.Wall;
            m_board[17, 22] = Item.Wall;
            m_board[17, 23] = Item.Pellet;
            m_board[17, 24] = Item.Wall;
            m_board[17, 25] = Item.Wall;
            m_board[17, 26] = Item.Pellet;
            m_board[17, 27] = Item.Wall;
            m_board[17, 28] = Item.Wall;
            m_board[17, 29] = Item.Pellet;
            m_board[17, 30] = Item.Wall;

            m_board[18, 0] = Item.Wall;
            m_board[18, 1] = Item.Pellet;
            m_board[18, 2] = Item.Wall;
            m_board[18, 3] = Item.Empty;
            m_board[18, 4] = Item.Wall;
            m_board[18, 5] = Item.Pellet;
            m_board[18, 6] = Item.Pellet;
            m_board[18, 7] = Item.Pellet;
            m_board[18, 8] = Item.Pellet;
            m_board[18, 9] = Item.Wall;
            m_board[18, 10] = Item.Wall;
            m_board[18, 11] = Item.Empty;
            m_board[18, 12] = Item.Empty;
            m_board[18, 13] = Item.Empty;
            m_board[18, 14] = Item.Empty;
            m_board[18, 15] = Item.Empty;
            m_board[18, 16] = Item.Empty;
            m_board[18, 17] = Item.Empty;
            m_board[18, 18] = Item.Empty;
            m_board[18, 19] = Item.Empty;
            m_board[18, 20] = Item.Pellet;
            m_board[18, 21] = Item.Wall;
            m_board[18, 22] = Item.Wall;
            m_board[18, 23] = Item.Pellet;
            m_board[18, 24] = Item.Pellet;
            m_board[18, 25] = Item.Pellet;
            m_board[18, 26] = Item.Pellet;
            m_board[18, 27] = Item.Wall;
            m_board[18, 28] = Item.Wall;
            m_board[18, 29] = Item.Pellet;
            m_board[18, 30] = Item.Wall;

            m_board[19, 0] = Item.Wall;
            m_board[19, 1] = Item.Pellet;
            m_board[19, 2] = Item.Wall;
            m_board[19, 3] = Item.Empty;
            m_board[19, 4] = Item.Wall;
            m_board[19, 5] = Item.Pellet;
            m_board[19, 6] = Item.Wall;
            m_board[19, 7] = Item.Wall;
            m_board[19, 8] = Item.Wall;
            m_board[19, 9] = Item.Wall;
            m_board[19, 10] = Item.Wall;
            m_board[19, 11] = Item.Wall;
            m_board[19, 12] = Item.Wall;
            m_board[19, 13] = Item.Wall;
            m_board[19, 14] = Item.Empty;
            m_board[19, 15] = Item.Wall;
            m_board[19, 16] = Item.Wall;
            m_board[19, 17] = Item.Wall;
            m_board[19, 18] = Item.Wall;
            m_board[19, 19] = Item.Wall;
            m_board[19, 20] = Item.Pellet;
            m_board[19, 21] = Item.Wall;
            m_board[19, 22] = Item.Wall;
            m_board[19, 23] = Item.Pellet;
            m_board[19, 24] = Item.Wall;
            m_board[19, 25] = Item.Wall;
            m_board[19, 26] = Item.Wall;
            m_board[19, 27] = Item.Wall;
            m_board[19, 28] = Item.Wall;
            m_board[19, 29] = Item.Pellet;
            m_board[19, 30] = Item.Wall;

            m_board[20, 0] = Item.Wall;
            m_board[20, 1] = Item.Pellet;
            m_board[20, 2] = Item.Wall;
            m_board[20, 3] = Item.Wall;
            m_board[20, 4] = Item.Wall;
            m_board[20, 5] = Item.Pellet;
            m_board[20, 6] = Item.Wall;
            m_board[20, 7] = Item.Wall;
            m_board[20, 8] = Item.Wall;
            m_board[20, 9] = Item.Wall;
            m_board[20, 10] = Item.Wall;
            m_board[20, 11] = Item.Wall;
            m_board[20, 12] = Item.Wall;
            m_board[20, 13] = Item.Wall;
            m_board[20, 14] = Item.Empty;
            m_board[20, 15] = Item.Wall;
            m_board[20, 16] = Item.Wall;
            m_board[20, 17] = Item.Wall;
            m_board[20, 18] = Item.Wall;
            m_board[20, 19] = Item.Wall;
            m_board[20, 20] = Item.Pellet;
            m_board[20, 21] = Item.Wall;
            m_board[20, 22] = Item.Wall;
            m_board[20, 23] = Item.Pellet;
            m_board[20, 24] = Item.Wall;
            m_board[20, 25] = Item.Wall;
            m_board[20, 26] = Item.Wall;
            m_board[20, 27] = Item.Wall;
            m_board[20, 28] = Item.Wall;
            m_board[20, 29] = Item.Pellet;
            m_board[20, 30] = Item.Wall;

            m_board[21, 0] = Item.Wall;
            m_board[21, 1] = Item.Pellet;
            m_board[21, 2] = Item.Pellet;
            m_board[21, 3] = Item.Pellet;
            m_board[21, 4] = Item.Pellet;
            m_board[21, 5] = Item.Pellet;
            m_board[21, 6] = Item.Pellet;
            m_board[21, 7] = Item.Pellet;
            m_board[21, 8] = Item.Pellet;
            m_board[21, 9] = Item.Pellet;
            m_board[21, 10] = Item.Pellet;
            m_board[21, 11] = Item.Pellet;
            m_board[21, 12] = Item.Pellet;
            m_board[21, 13] = Item.Pellet;
            m_board[21, 14] = Item.Pellet;
            m_board[21, 15] = Item.Pellet;
            m_board[21, 16] = Item.Pellet;
            m_board[21, 17] = Item.Pellet;
            m_board[21, 18] = Item.Pellet;
            m_board[21, 19] = Item.Pellet;
            m_board[21, 20] = Item.Pellet;
            m_board[21, 21] = Item.Pellet;
            m_board[21, 22] = Item.Pellet;
            m_board[21, 23] = Item.Pellet;
            m_board[21, 24] = Item.Pellet;
            m_board[21, 25] = Item.Pellet;
            m_board[21, 26] = Item.Pellet;
            m_board[21, 27] = Item.Wall;
            m_board[21, 28] = Item.Wall;
            m_board[21, 29] = Item.Pellet;
            m_board[21, 30] = Item.Wall;

            m_board[22, 0] = Item.Wall;
            m_board[22, 1] = Item.Pellet;
            m_board[22, 2] = Item.Wall;
            m_board[22, 3] = Item.Wall;
            m_board[22, 4] = Item.Wall;
            m_board[22, 5] = Item.Pellet;
            m_board[22, 6] = Item.Wall;
            m_board[22, 7] = Item.Wall;
            m_board[22, 8] = Item.Pellet;
            m_board[22, 9] = Item.Wall;
            m_board[22, 10] = Item.Wall;
            m_board[22, 11] = Item.Wall;
            m_board[22, 12] = Item.Wall;
            m_board[22, 13] = Item.Wall;
            m_board[22, 14] = Item.Empty;
            m_board[22, 15] = Item.Wall;
            m_board[22, 16] = Item.Wall;
            m_board[22, 17] = Item.Wall;
            m_board[22, 18] = Item.Wall;
            m_board[22, 19] = Item.Wall;
            m_board[22, 20] = Item.Pellet;
            m_board[22, 21] = Item.Wall;
            m_board[22, 22] = Item.Wall;
            m_board[22, 23] = Item.Wall;
            m_board[22, 24] = Item.Wall;
            m_board[22, 25] = Item.Wall;
            m_board[22, 26] = Item.Pellet;
            m_board[22, 27] = Item.Wall;
            m_board[22, 28] = Item.Wall;
            m_board[22, 29] = Item.Pellet;
            m_board[22, 30] = Item.Wall;

            m_board[23, 0] = Item.Wall;
            m_board[23, 1] = Item.Pellet;
            m_board[23, 2] = Item.Wall;
            m_board[23, 3] = Item.Empty;
            m_board[23, 4] = Item.Wall;
            m_board[23, 5] = Item.Pellet;
            m_board[23, 6] = Item.Wall;
            m_board[23, 7] = Item.Wall;
            m_board[23, 8] = Item.Pellet;
            m_board[23, 9] = Item.Wall;
            m_board[23, 10] = Item.Empty;
            m_board[23, 11] = Item.Empty;
            m_board[23, 12] = Item.Empty;
            m_board[23, 13] = Item.Wall;
            m_board[23, 14] = Item.Empty;
            m_board[23, 15] = Item.Wall;
            m_board[23, 16] = Item.Empty;
            m_board[23, 17] = Item.Empty;
            m_board[23, 18] = Item.Empty;
            m_board[23, 19] = Item.Wall;
            m_board[23, 20] = Item.Pellet;
            m_board[23, 21] = Item.Wall;
            m_board[23, 22] = Item.Wall;
            m_board[23, 23] = Item.Wall;
            m_board[23, 24] = Item.Wall;
            m_board[23, 25] = Item.Wall;
            m_board[23, 26] = Item.Pellet;
            m_board[23, 27] = Item.Wall;
            m_board[23, 28] = Item.Wall;
            m_board[23, 29] = Item.Pellet;
            m_board[23, 30] = Item.Wall;

            m_board[24, 0] = Item.Wall;
            m_board[24, 1] = Item.Pellet;
            m_board[24, 2] = Item.Wall;
            m_board[24, 3] = Item.Empty;
            m_board[24, 4] = Item.Wall;
            m_board[24, 5] = Item.Pellet;
            m_board[24, 6] = Item.Wall;
            m_board[24, 7] = Item.Wall;
            m_board[24, 8] = Item.Pellet;
            m_board[24, 9] = Item.Wall;
            m_board[24, 10] = Item.Empty;
            m_board[24, 11] = Item.Empty;
            m_board[24, 12] = Item.Empty;
            m_board[24, 13] = Item.Wall;
            m_board[24, 14] = Item.Empty;
            m_board[24, 15] = Item.Wall;
            m_board[24, 16] = Item.Empty;
            m_board[24, 17] = Item.Empty;
            m_board[24, 18] = Item.Empty;
            m_board[24, 19] = Item.Wall;
            m_board[24, 20] = Item.Pellet;
            m_board[24, 21] = Item.Wall;
            m_board[24, 22] = Item.Wall;
            m_board[24, 23] = Item.Pellet;
            m_board[24, 24] = Item.Pellet;
            m_board[24, 25] = Item.Pellet;
            m_board[24, 26] = Item.Pellet;
            m_board[24, 27] = Item.Wall;
            m_board[24, 28] = Item.Wall;
            m_board[24, 29] = Item.Pellet;
            m_board[24, 30] = Item.Wall;

            m_board[25, 0] = Item.Wall;
            m_board[25, 1] = Item.Pellet;
            m_board[25, 2] = Item.Wall;
            m_board[25, 3] = Item.Wall;
            m_board[25, 4] = Item.Wall;
            m_board[25, 5] = Item.Pellet;
            m_board[25, 6] = Item.Wall;
            m_board[25, 7] = Item.Wall;
            m_board[25, 8] = Item.Pellet;
            m_board[25, 9] = Item.Wall;
            m_board[25, 10] = Item.Empty;
            m_board[25, 11] = Item.Empty;
            m_board[25, 12] = Item.Empty;
            m_board[25, 13] = Item.Wall;
            m_board[25, 14] = Item.Empty;
            m_board[25, 15] = Item.Wall;
            m_board[25, 16] = Item.Empty;
            m_board[25, 17] = Item.Empty;
            m_board[25, 18] = Item.Empty;
            m_board[25, 19] = Item.Wall;
            m_board[25, 20] = Item.Pellet;
            m_board[25, 21] = Item.Wall;
            m_board[25, 22] = Item.Wall;
            m_board[25, 23] = Item.Pellet;
            m_board[25, 24] = Item.Wall;
            m_board[25, 25] = Item.Wall;
            m_board[25, 26] = Item.Pellet;
            m_board[25, 27] = Item.Wall;
            m_board[25, 28] = Item.Wall;
            m_board[25, 29] = Item.Pellet;
            m_board[25, 30] = Item.Wall;

            m_board[26, 0] = Item.Wall;
            m_board[26, 1] = Item.Pellet;
            m_board[26, 2] = Item.Pellet;
            m_board[26, 3] = Item.PowerPellet;
            m_board[26, 4] = Item.Pellet;
            m_board[26, 5] = Item.Pellet;
            m_board[26, 6] = Item.Pellet;
            m_board[26, 7] = Item.Pellet;
            m_board[26, 8] = Item.Pellet;
            m_board[26, 9] = Item.Wall;
            m_board[26, 10] = Item.Empty;
            m_board[26, 11] = Item.Empty;
            m_board[26, 12] = Item.Empty;
            m_board[26, 13] = Item.Wall;
            m_board[26, 14] = Item.Empty;
            m_board[26, 15] = Item.Wall;
            m_board[26, 16] = Item.Empty;
            m_board[26, 17] = Item.Empty;
            m_board[26, 18] = Item.Empty;
            m_board[26, 19] = Item.Wall;
            m_board[26, 20] = Item.Pellet;
            m_board[26, 21] = Item.Pellet;
            m_board[26, 22] = Item.Pellet;
            m_board[26, 23] = Item.PowerPellet;
            m_board[26, 24] = Item.Wall;
            m_board[26, 25] = Item.Wall;
            m_board[26, 26] = Item.Pellet;
            m_board[26, 27] = Item.Pellet;
            m_board[26, 28] = Item.Pellet;
            m_board[26, 29] = Item.Pellet;
            m_board[26, 30] = Item.Wall;

            m_board[27, 0] = Item.Wall;
            m_board[27, 1] = Item.Wall;
            m_board[27, 2] = Item.Wall;
            m_board[27, 3] = Item.Wall;
            m_board[27, 4] = Item.Wall;
            m_board[27, 5] = Item.Wall;
            m_board[27, 6] = Item.Wall;
            m_board[27, 7] = Item.Wall;
            m_board[27, 8] = Item.Wall;
            m_board[27, 9] = Item.Wall;
            m_board[27, 10] = Item.Empty;
            m_board[27, 11] = Item.Empty;
            m_board[27, 12] = Item.Empty;
            m_board[27, 13] = Item.Wall;
            m_board[27, 14] = Item.Empty;
            m_board[27, 15] = Item.Wall;
            m_board[27, 16] = Item.Empty;
            m_board[27, 17] = Item.Empty;
            m_board[27, 18] = Item.Empty;
            m_board[27, 19] = Item.Wall;
            m_board[27, 20] = Item.Wall;
            m_board[27, 21] = Item.Wall;
            m_board[27, 22] = Item.Wall;
            m_board[27, 23] = Item.Wall;
            m_board[27, 24] = Item.Wall;
            m_board[27, 25] = Item.Wall;
            m_board[27, 26] = Item.Wall;
            m_board[27, 27] = Item.Wall;
            m_board[27, 28] = Item.Wall;
            m_board[27, 29] = Item.Wall;
            m_board[27, 30] = Item.Wall;
        }

        #endregion

        #region Private data

        // The number of ghosts in the game.
        // (Accessed via the static NumberOfGhosts property.)
        private const int NUM_GHOSTS = 4;

        // The board, held as a two-dimensional array of items...
        private const int BOARD_WIDTH = 28;
        private const int BOARD_HEIGHT = 31;
        private Item[,] m_board = new Item[BOARD_WIDTH, BOARD_HEIGHT];

        // The position and direction of the Pac-Man...
        private PlayerInfo m_pacManInfo = new PlayerInfo();

        // The positions of the four ghosts...
        private PlayerInfo[] m_ghostInfos = new PlayerInfo[NUM_GHOSTS];

        // If Pac-Man has eaten a power-pellet, this number will be positive,
        // and holds the number of turns remaining in the powered up state...
        private int m_powerUpTurnsRemaining = 0;

        // The position that Pac-Man seems to be if a ghost cannot see it...
        private static Point m_unknownPacManPosition = new Point(-1, -1);

        #endregion
    }
}
